package database

import (
	"errors"
	"github.com/garyburd/redigo/redis"
	"time"
)

var redisPool *redis.Pool

type RedisConf struct {
	Addr    string `yaml:"addr"`
	MaxIdle int    `yaml:"maxIdle"`
	MaxOpen int    `yaml:"maxOpen"`
	DB      int    `yaml:"db"`
}

// 初始化redis
func InitRedis(conf *RedisConf) (err error) {
	redisPool = &redis.Pool{
		MaxIdle:     conf.MaxIdle,
		MaxActive:   conf.MaxOpen,
		IdleTimeout: time.Duration(30) * time.Minute,
		Dial: func() (redis.Conn, error) {
			return redis.Dial("tcp", conf.Addr, redis.DialDatabase(conf.DB))
		},
	}

	conn := GetRedis()
	defer conn.Close()

	if r, _ := redis.String(conn.Do("PING")); r != "PONG" {
		err = errors.New("redis connect failed")
	}

	return
}

// 获取redis连接
func GetRedis() redis.Conn {
	return redisPool.Get()
}

func CloseRedis() {
	if redisPool != nil {
		_ = redisPool.Close()
	}
}

//设置缓存
func Set(key, val string, ttl time.Duration) error {
	conn := GetRedis()
	defer conn.Close()

	r, err := redis.String(conn.Do("SET", key, val, "EX", ttl.Seconds()))

	if err != nil {
		return err
	}

	if r != "OK" {
		return errors.New("NOT OK")
	}

	return nil
}

//设置缓存
func SetBin(key string, val []byte, ttl time.Duration) error {
	conn := GetRedis()
	defer conn.Close()

	r, err := conn.Do("SET", key, val, "EX", ttl.Seconds())

	if err != nil {
		return err
	}

	if r != int64(1) {
		return errors.New("NOT OK")
	}
	return nil
}

//获取缓存
func Get(key string) (string, error) {
	conn := GetRedis()
	defer conn.Close()

	r, err := redis.String(conn.Do("GET", key))

	if err != nil {
		return "", err
	}

	return r, nil
}

//获取缓存
func GetBin(key string) ([]byte, error) {
	conn := GetRedis()
	defer conn.Close()

	r, err := redis.Bytes(conn.Do("GET", key))

	if err != nil {
		return []byte{}, err
	}

	return r, nil
}

func Del(key string) error {
	conn := GetRedis()
	defer conn.Close()
	_, err := conn.Do("DEL", key)
	if err != nil {
		return err
	} else {
		return nil
	}
}
